package com.ljy.farm.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ljy.farm.constants.BusinessConstants;
import com.ljy.farm.constants.ExceptionConstants;
import com.ljy.farm.datasource.entities.Tenant;
import com.ljy.farm.datasource.entities.User;
import com.ljy.farm.datasource.entities.UserEx;
import com.ljy.farm.datasource.entities.UserBusiness;
import com.ljy.farm.datasource.vo.TreeNodeEx;
import com.ljy.farm.exception.BusinessParamCheckingException;
import com.ljy.farm.service.log.LogService;
import com.ljy.farm.service.tenant.TenantService;
import com.ljy.farm.service.user.UserService;
import com.ljy.farm.service.userBusiness.UserBusinessService;
import com.ljy.farm.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/user")
public class UserController {
    private Logger logger = LoggerFactory.getLogger(UserController.class);
// http://localhost:8080/user/login
    @Value("${manage.roleId}")
    private Integer manageRoleId;

    @Resource
    private UserService userService;

    @Resource
    private TenantService tenantService;

    @Resource
    private LogService logService;

    @Resource
    private UserBusinessService userBusinessService;

    private static String message = "成功";
    private static final String HTTP = "http://";
    private static final String CODE_OK = "200";

    @PostMapping(value = "/login")
    public BaseResponseInfo login(@RequestParam(value = "loginName", required = false) String loginName,
                                  @RequestParam(value = "password", required = false) String password,
                                  HttpServletRequest request) throws Exception {
        logger.info("============用户登录 login 方法调用开始==============");
        String msgTip = "";
        User user = null;
        BaseResponseInfo res = new BaseResponseInfo();
        try {
            loginName = loginName.trim();
            password = password.trim();
            //判断用户是否已经登录过，登录过不再处理
            Object userInfo = request.getSession().getAttribute("user");
            User sessionUser = new User();
            if (userInfo != null) {
                sessionUser = (User) userInfo;
            }
            if (sessionUser != null && loginName.equalsIgnoreCase(sessionUser.getLoginName())) {
                logger.info("====用户 " + loginName + "已经登录过, login 方法调用结束====");
                msgTip = "user already login";
            }
            //获取用户状态
            int userStatus = -1;
            try {
                request.getSession().removeAttribute("tenantId");
                userStatus = userService.validateUser(loginName, password);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error(">>>>>>>>>>>>>用户  " + loginName + " 登录 login 方法 访问服务层异常====", e);
                msgTip = "access service exception";
            }
            switch (userStatus) {
                case ExceptionCodeConstants.UserExceptionCode.USER_NOT_EXIST:
                    msgTip = "user is not exist";
                    break;
                case ExceptionCodeConstants.UserExceptionCode.USER_PASSWORD_ERROR:
                    msgTip = "user password error";
                    break;
                case ExceptionCodeConstants.UserExceptionCode.BLACK_USER:
                    msgTip = "user is black";
                    break;
                case ExceptionCodeConstants.UserExceptionCode.USER_ACCESS_EXCEPTION:
                    msgTip = "access service error";
                    break;
                default:
                    try {
                        msgTip = "user can login";
                        //验证通过 ，可以登录，放入session，记录登录日志
                        user = userService.getUserByLoginName(loginName);
                        request.getSession().setAttribute("user", user);
                        if (user.getTenantId() != null) {
                            Tenant tenant = tenantService.getTenantByTenantId(user.getTenantId());
                            if (tenant != null) {
                                Long tenantId = tenant.getTenantId();
                                Integer userNumLimit = tenant.getUserNumLimit();
                                Integer billsNumLimit = tenant.getBillsNumLimit();
                                if (tenantId != null) {
                                    request.getSession().setAttribute("tenantId", tenantId); //租户tenantId
                                    request.getSession().setAttribute("userNumLimit", userNumLimit); //用户限制数
                                    request.getSession().setAttribute("billsNumLimit", billsNumLimit); //单据限制数
                                }
                            }
                        }
                        logService.insertLog("用户",
                                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_LOGIN).append(user.getId()).toString(),
                                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.error(">>>>>>>>>>>>>>>查询用户名为:" + loginName + " ，用户信息异常", e);
                    }
                    break;
            }
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("msgTip", msgTip);
            /**
             * 在IE模式下，无法获取到user数据，
             * 在此处明确添加上user信息
             * */
            if (user != null) {
                data.put("user", user);
            }
            res.code = 200;
            res.data = data;
            logger.info("===============用户登录 login 方法调用结束===============");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            res.code = 500;
            res.data = "用户登录失败";
        }
        return res;
    }

    @GetMapping(value = "/getUserSession")
    public BaseResponseInfo getSessionUser(HttpServletRequest request) throws Exception {
        BaseResponseInfo res = new BaseResponseInfo();
        try {
            Map<String, Object> data = new HashMap<String, Object>();
            Object userInfo = request.getSession().getAttribute("user");
            if (userInfo != null) {
                User user = (User) userInfo;
                user.setPassword(null);
                data.put("user", user);
            }
            res.code = 200;
            res.data = data;
        } catch (Exception e) {
            e.printStackTrace();
            res.code = 500;
            res.data = "获取session失败";
        }
        return res;
    }

    @GetMapping(value = "/logout")
    public BaseResponseInfo logout(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BaseResponseInfo res = new BaseResponseInfo();
        try {
            request.getSession().removeAttribute("user");
            request.getSession().removeAttribute("tenantId");
            request.getSession().removeAttribute("userNumLimit");
            request.getSession().removeAttribute("billsNumLimit");
            response.sendRedirect("/login.html");
        } catch (Exception e) {
            e.printStackTrace();
            res.code = 500;
            res.data = "退出失败";
        }
        return res;
    }

    @PostMapping(value = "/resetPwd")
    public String resetPwd(@RequestParam(value = "id", required = false) Long id,
                           HttpServletRequest request) throws Exception {
        if (id == null) {
            return "参数id不能为空";
        }
        Map<String, Object> objectMap = new HashMap<String, Object>();
        String password = "123456";
        String md5Pwd = Tools.md5Encryp(password);
        int update = userService.resetPwd(md5Pwd, id);
        if (update > 0) {
            return ResponseJsonUtil.returnJson(objectMap, message, ErpInfo.OK.code);
        } else {
            return ResponseJsonUtil.returnJson(objectMap, message, ErpInfo.ERROR.code);
        }
    }

    @PostMapping(value = "/updatePwd")
    public String updatePwd(@RequestParam("userId") Long userId, @RequestParam("password") String password,
                            @RequestParam("oldpwd") String oldpwd, HttpServletRequest request) throws Exception {
        Integer flag = 0;
        Map<String, Object> objectMap = new HashMap<String, Object>();
        try {
            User user = userService.getUser(userId);
            String oldPassword = Tools.md5Encryp(oldpwd);
            String md5Pwd = Tools.md5Encryp(password);
            //必须和原始密码一致才可以更新密码
            if (user.getLoginName().equals("jsh")) {
                flag = 3; //管理员jsh不能修改密码
            } else if (oldPassword.equalsIgnoreCase(user.getPassword())) {
                user.setPassword(md5Pwd);
                flag = userService.updateUserByObj(user); //1-成功
            } else {
                flag = 2; //原始密码输入错误
            }
            objectMap.put("status", flag);
            if (flag > 0) {
                return ResponseJsonUtil.returnJson(objectMap, message, ErpInfo.OK.code);
            } else {
                return ResponseJsonUtil.returnJson(objectMap, message, ErpInfo.ERROR.code);
            }
        } catch (Exception e) {
            logger.error(">>>>>>>>>>>>>修改用户ID为 ： " + userId + "密码信息失败", e);
            flag = 3;
            objectMap.put("status", flag);
            return ResponseJsonUtil.returnJson(objectMap, message, ErpInfo.ERROR.code);
        }
    }

    /**
     * 获取全部用户数据列表
     *
     * @param request
     * @return
     */
    @GetMapping(value = "/getAllList")
    public BaseResponseInfo getAllList(HttpServletRequest request) throws Exception {
        BaseResponseInfo res = new BaseResponseInfo();
        try {
            Map<String, Object> data = new HashMap<String, Object>();
            List<User> dataList = userService.getUser();
            if (dataList != null) {
                data.put("userList", dataList);
            }
            res.code = 200;
            res.data = data;
        } catch (Exception e) {
            e.printStackTrace();
            res.code = 500;
            res.data = "获取失败";
        }
        return res;
    }

    /**
     * create by: cjl
     * description:
     * 新增用户及机构和用户关系
     * create time: 2019/3/8 16:06
     *
     * @return java.lang.Object
     * @Param: beanJson
     */
    @PostMapping("/addUser")
    @ResponseBody
    public Object addUser(@RequestParam("info") String beanJson, HttpServletRequest request) throws Exception {
        JSONObject result = ExceptionConstants.standardSuccess();
        Object userNumLimitObj = request.getSession().getAttribute("userNumLimit");
        if (userNumLimitObj == null) {
            throw new BusinessParamCheckingException(ExceptionConstants.SERVICE_SYSTEM_ERROR_CODE, "会话已失效或未登录，无法获取用户数限制，请重新登录后再试");
        }
        Long userNumLimit = Long.parseLong(userNumLimitObj.toString());
        Long count = userService.countUser(null, null);
        if (count >= userNumLimit) {
            throw new BusinessParamCheckingException(ExceptionConstants.USER_OVER_LIMIT_FAILED_CODE,
                    ExceptionConstants.USER_OVER_LIMIT_FAILED_MSG);
        } else {
            UserEx ue = JSON.parseObject(beanJson, UserEx.class);
            userService.addUserAndOrgUserRel(ue);
        }
        return result;
    }


    /**
     * 注册用户
     *
     * @param loginName
     * @param password
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/registerUser")
    public Object registerUser(@RequestParam(value = "loginName", required = false) String loginName,
                               @RequestParam(value = "password", required = false) String password,
                               HttpServletRequest request) throws Exception {
        JSONObject result = ExceptionConstants.standardSuccess();
        UserEx ue = new UserEx();
        ue.setUsername(loginName);
        ue.setLoginName(loginName);
        ue.setPassword(password);
        userService.checkUserNameAndLoginName(ue); //检查用户名和登录名
        ue = userService.registerUser(ue, manageRoleId, request);
        return result;
    }

    /**
     * create by: cjl
     * description:
     * 修改用户及机构和用户关系
     * create time: 2019/3/8 16:06
     *
     * @return java.lang.Object
     * @Param: beanJson
     */
    @PostMapping("/updateUser")
    @ResponseBody
    public Object updateUser(@RequestParam("info") String beanJson, @RequestParam(value = "id", required = false) Long id, HttpServletRequest request) throws Exception {
        if (id == null) {
            return "参数id不能为空";
        }
        JSONObject result = ExceptionConstants.standardSuccess();
        
        try {
            // 获取当前登录用户
            User currentUser = userService.getCurrentUser();
            if (currentUser == null) {
                logger.error("用户未登录");
                throw new BusinessParamCheckingException(ExceptionConstants.SERVICE_SYSTEM_ERROR_CODE, "用户未登录");
            }
            
            logger.info("当前登录用户ID: {}, 要修改的用户ID: {}", currentUser.getId(), id);
            
            // 权限控制：普通用户只能修改自己的信息，管理员可以修改任何用户的信息
            boolean isAdmin = "admin".equals(currentUser.getLoginName()) || "jsh".equals(currentUser.getLoginName());
            boolean isModifyingSelf = currentUser.getId().equals(id);
            
            if (!isAdmin && !isModifyingSelf) {
                logger.error("权限不足：用户 {} 尝试修改用户 {} 的信息", currentUser.getLoginName(), id);
                throw new BusinessParamCheckingException(ExceptionConstants.SERVICE_SYSTEM_ERROR_CODE, "权限不足，只能修改自己的信息");
            }
            
            UserEx ue = JSON.parseObject(beanJson, UserEx.class);
            ue.setId(id);
            
            // 如果是普通用户修改自己的信息，不允许修改机构相关信息
            if (!isAdmin && isModifyingSelf) {
                // 保留原有的机构信息，不允许修改
                User originalUser = userService.getUser(id);
                if (originalUser != null) {
                    // 对于普通用户，我们只允许修改基本信息，不允许修改机构相关信息
                    // 机构相关信息会在updateUserAndOrgUserRel方法中保持不变
                    logger.info("普通用户修改自己的信息，保留原有机构信息");
                }
            }
            
            UserEx updatedUserEx = userService.updateUserAndOrgUserRel(ue);

            // 更新session中的用户信息
            if (isModifyingSelf) {
                request.getSession().setAttribute("user", updatedUserEx);
            }
            
            logger.info("用户信息更新成功：用户ID {}", id);
            
        } catch (BusinessParamCheckingException e) {
            logger.error("更新用户信息失败：{}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("更新用户信息时发生异常：", e);
            throw new BusinessParamCheckingException(ExceptionConstants.SERVICE_SYSTEM_ERROR_CODE, "更新用户信息失败：" + e.getMessage());
        }
        
        return result;
    }

    @PostMapping("/deleteUser")
    @ResponseBody
    public Object deleteUser(@RequestParam("ids") String ids) throws Exception {
        JSONObject result = ExceptionConstants.standardSuccess();
        userService.batDeleteUser(ids);
        return result;
    }

    @PostMapping("/batchDeleteUser")
    @ResponseBody
    public Object batchDeleteUser(@RequestParam("ids") String ids) throws Exception {
        JSONObject result = ExceptionConstants.standardSuccess();
        userService.batDeleteUser(ids);
        return result;
    }

    @RequestMapping("/getOrganizationUserTree")
    public JSONArray getOrganizationUserTree() throws Exception {
        JSONArray arr = new JSONArray();
        List<TreeNodeEx> organizationUserTree = userService.getOrganizationUserTree();
        if (organizationUserTree != null && organizationUserTree.size() > 0) {
            for (TreeNodeEx node : organizationUserTree) {
                String str = JSON.toJSONString(node);
                JSONObject obj = JSON.parseObject(str);
                arr.add(obj);
            }
        }
        return arr;
    }

    /**
     * 获取用户身份信息
     *
     * @param request
     * @return
     * @throws Exception
     */
    @GetMapping("/getUserRoleInfo")
    public BaseResponseInfo getUserRoleInfo(HttpServletRequest request) throws Exception {
        BaseResponseInfo res = new BaseResponseInfo();
        try {
            Map<String, Object> data = new HashMap<String, Object>();
            Object userInfo = request.getSession().getAttribute("user");
            if (userInfo != null) {
                User user = (User) userInfo;
                
                // 获取用户角色信息
                List<UserBusiness> userRoles = userBusinessService.findRoleByUserId(user.getId().toString());
                String roleName = "普通用户";
                
                if (userRoles != null && !userRoles.isEmpty()) {
                    String roleIds = userRoles.get(0).getValue();
                    if (roleIds != null && !roleIds.isEmpty()) {
                        // 解析角色ID，格式如：[1][2]
                        String[] roleIdArray = roleIds.replace("[", "").replace("]", "").split("\\]\\[");
                        if (roleIdArray.length > 0) {
                            Long roleId = Long.parseLong(roleIdArray[0]);
                            
                            // 根据角色ID判断用户身份
                            switch (roleId.intValue()) {
                                case 4:
                                    roleName = "管理员";
                                    break;
                                case 5:
                                    roleName = "仓管员";
                                    break;
                                case 10:
                                    roleName = "租户";
                                    break;
                                case 25:
                                    roleName = "财务管理员";
                                    break;
                                default:
                                    roleName = "普通用户";
                                    break;
                            }
                        }
                    }
                }
                
                // 判断是否为系统管理员
                if ("admin".equals(user.getLoginName()) || "jsh".equals(user.getLoginName())) {
                    roleName = "系统管理员";
                }
                
                data.put("roleName", roleName);
                data.put("userId", user.getId());
                data.put("username", user.getUsername());
                data.put("loginName", user.getLoginName());
            }
            res.code = 200;
            res.data = data;
        } catch (Exception e) {
            e.printStackTrace();
            res.code = 500;
            res.data = "获取用户身份信息失败";
        }
        return res;
    }
}
